package com.own.component.store.core.confirm.util;

import com.own.component.store.core.Store;
import com.own.component.store.core.confirm.aop.ConfirmAop;
import com.own.component.store.core.confirm.model.ConfirmModel;
import com.own.component.store.core.constant.ConstantConfirmCommon;
import com.own.component.store.core.exception.ConfirmException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.UUID;

/**
 * RequestConfirmUtil
 *
 * @author chenxueli
 * @date 2024-05-15 15:04:00
 */
@Slf4j
@Component
public class RequestConfirmUtil {

    @Resource
    private Store<String> store;

    /**
     * 验证二次确认信息
     *
     * @author chenxueli
     * @date 2022-06-15 03:14:15
     */
    public void check() {
        check(ConstantConfirmCommon.DEFAULT_MESSAGE);
    }

    /**
     * 验证二次确认信息
     *
     * @param message 二次确认的提示文字
     * @author chenxueli
     * @date 2022-06-15 03:14:15
     */
    public void check(String message) {
        check(ConstantConfirmCommon.DEFAULT_CODE, ConstantConfirmCommon.DEFAULT_KEY_FOR_BUSINESS, message);
    }

    /**
     * 验证二次确认信息
     *
     * @param code    二次确认的错误码
     * @param key     二次确认的key
     * @param message 二次确认的提示文字
     * @author chenxueli
     * @date 2022-06-15 03:14:15
     */
    public void check(String code, String key, String message) {
        check(new ConfirmModel()
                .setCode(code)
                .setKey(key)
                .setMessage(message)
                .setEnforce(ConstantConfirmCommon.DEFAULT_ENFORCE)
                .setExpire(ConstantConfirmCommon.DEFAULT_EXPIRE)
                .setEnforceValue(ConstantConfirmCommon.DEFAULT_ENFORCE_VALUE)
                .setModule(ConstantConfirmCommon.DEFAULT_MODULE)
                .setValue(ConstantConfirmCommon.DEFAULT_VALUE)
                .setAop(false)
        );
    }

    /**
     * 验证二次确认信息
     *
     * @param confirmAop 二次确认切面的数据
     * @author chenxueli
     * @date 2022-06-15 03:14:15
     */
    public void check(ConfirmAop confirmAop) {
        // 判断是否是swagger接口模式
        check(new ConfirmModel(confirmAop).setAop(true));
    }

    /**
     * 验证二次确认信息
     *
     * @param model 二次确认的源数据对象
     * @author chenxueli
     * @date 2022-06-15 03:14:15
     */
    public void check(ConfirmModel model) {
        if (model.isValue()) {
            // 获取参数中带有的值
            var attributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
            if (attributes == null) {
                return;
            }
            var request = attributes.getRequest();
            if (model.isAop()) {
                var skip = request.getParameter("confirm_skip");
                if (ConstantConfirmCommon.SKIP_FIELD.equals(skip)) {
                    return;
                }
            }
            var value = request.getParameter(model.getKey());
            // 是否有强制执行的标志
            if (model.isEnforce() && model.getEnforceValue().equals(value)) {
                return;
            }
            var atomic = store.atomic();
            var key = String.format("double:confirm:%s:%s", model.getModule(), value);
            if (!atomic.contains(key)) {
                var token = UUID.randomUUID().toString();
                atomic.incrementAndGet(String.format("double:confirm:%s:%s", model.getModule(), token), Duration.ofSeconds(60L));
                throw new ConfirmException(model, token);
            }
            atomic.remove(key);
        }
    }

}
